package com.topc.problem.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.topc.base.exception.Asserts;
import com.topc.base.model.PageParams;
import com.topc.base.model.PageResult;
import com.topc.base.utils.PageUtils;
import com.topc.problem.mapper.ProblemTagMapper;
import com.topc.problem.model.dto.QueryTagDto;
import com.topc.problem.model.po.ProblemInfo;
import com.topc.problem.model.po.ProblemTag;
import com.topc.problem.model.vo.ParentTagVo;
import com.topc.problem.model.vo.TagTreeShowVo;
import com.topc.problem.service.IProblemTagMidService;
import com.topc.problem.service.IProblemTagService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class ProblemTagServiceImpl extends ServiceImpl<ProblemTagMapper, ProblemTag> implements IProblemTagService {

    @Autowired
    private IProblemTagMidService problemTagMidService;


    @Override
    public PageResult<ProblemTag> searchByPage(PageParams pageParams, QueryTagDto queryTagDto) {
        LambdaQueryWrapper<ProblemTag> query = new LambdaQueryWrapper<>();
        query.like(ObjectUtil.isNotEmpty(queryTagDto.getTagName()), ProblemTag::getName, queryTagDto.getTagName())
                .eq(queryTagDto.getParentId() != -1, ProblemTag::getParentId, queryTagDto.getParentId())
                .eq(queryTagDto.getIsParent() != -1, ProblemTag::getIsParent, queryTagDto.getIsParent());
        return PageUtils.pageToResult(this.getBaseMapper().selectPage(pageParams.page(), query));
    }


    @Override
    public List<ParentTagVo> getParentTagList() {
        LambdaQueryWrapper<ProblemTag> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ProblemTag::getIsParent, 1);
        List<ProblemTag> list = this.list(queryWrapper);
        List<ParentTagVo> collect = list.stream().map(problemTag -> {
            ParentTagVo parentTagVo = new ParentTagVo();
            BeanUtil.copyProperties(problemTag, parentTagVo);
            return parentTagVo;
        }).collect(Collectors.toList());
        return collect;
    }

    @Override
    public void addTagInfo(ProblemTag problemTag) {
        boolean save = this.save(problemTag);
        if (!save) Asserts.fail("添加失败");
    }

    @Override
    public void delTagInfo(Long tagId) {
        LambdaUpdateWrapper<ProblemTag> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(ProblemTag::getParentId, tagId).or().eq(ProblemTag::getId, tagId);
        boolean remove = this.remove(updateWrapper);
        if (!remove) Asserts.fail("删除失败");
    }

    @Override
    public void updateTagInfo(ProblemTag problemTag) {
        boolean save = this.updateById(problemTag);
        if (!save) Asserts.fail("更新失败");
    }

    @Override
    public List<TagTreeShowVo> getTagTreeShowVo() {
        List<ProblemTag> list = this.list();
        Map<Long, TagTreeShowVo> collect = list.stream().filter(problemTag -> problemTag.getIsParent() == 1)
                .map(TagTreeShowVo::new).collect(Collectors.toMap(TagTreeShowVo::getId
                        , tagTreeShowVo -> tagTreeShowVo, (value1, value2) -> value1));
        list.stream().filter(problemTag -> problemTag.getIsParent() == 0)
                .forEach(problemTag -> {
                    TagTreeShowVo tagTreeShowVo = collect.get(problemTag.getParentId());
                    if (ObjectUtil.isEmpty(tagTreeShowVo)) return;
                    tagTreeShowVo.addChildren(new TagTreeShowVo(problemTag));
                });
        return collect.values().stream().collect(Collectors.toList());
    }

    @Override
    public List<Long> getTagIds(Long problemId) {
        List<Long> tags = this.getBaseMapper().getTagIds(problemId);
        return tags;
    }

    @Override
    public List<ProblemTag> getTags(Long problemId) {
        List<ProblemTag> tags = this.getBaseMapper().getTags(problemId);
        return tags;
    }
}
